/*
MayPack v0.1
Copyright (c) 2021 Majjcom
licence:	MIT
Date:		2021/12/18
FILE:		test.cpp
*/
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>

#include "maypack/include/maypack.h"
#include "include/cmdline.h"

using namespace std;

int pack(int argc, char** argv)
{
	cmdline::parser comm;
	comm.set_program_name("maypack");
	comm.add<string>("fout", 'o', "File out", false, "out");
	comm.add("pack", '\0', "Packup Files");
	comm.parse_check(argc, argv);
	comm.parse(argc, argv);
	string fout = comm.get<string>("fout") + ".pack";
	if (comm.rest().size() == 0)
	{
		cerr << "\033[31mYou have to input some files...\033[0m" << endl;
		return 1;
	}
	int rc = maypack::packUp(comm.rest(), comm.rest().size(), fout.c_str());
	switch (rc)
	{
	case 1:
		cerr << "\033[31mInput Files error, please check your inputs...\033[0m" << endl;
		return 1;
		break;
	case 2:
		cerr << "\033[31mPackage file not exists, please check your inputs...\033[0m" << endl;
		return 1;
		break;
	case 3:
		cerr << "\033[31mPackage name error, please check output name...\033[0m" << endl;
		return 1;
		break;
	}
	return 0;
}

int unpack(int argc, char** argv)
{
	cmdline::parser comm;
	comm.set_program_name("maypack");
	comm.add<string>("fin", 'i', "File out", false, "out.pack");
	comm.add<string>("file", 'f', "Target file", true);
	comm.add("unpack", '\0', "Packup Files");
	comm.parse_check(argc, argv);
	comm.parse(argc, argv);
	string fin = comm.get<string>("fin");
	string fout = comm.get<string>("file");
	const char* fin_c = fin.c_str();
	const char* fout_c = fout.c_str();
	maypack::Package pack(fin_c);
	int rc = pack.unPack(fout_c);
	pack.close();
	switch (rc)
	{
	case 1:
		cerr << "\033[31mFile not exists...\033[0m" << endl;
		return 1;
		break;
	case 2:
		cerr << "\033[31mPackage file not exists...\033[0m" << endl;
		return 1;
		break;
	}
	return 0;
}

int list(int argc, char** argv)
{
	cmdline::parser comm;
	comm.set_program_name("maypack");
	comm.add<string>("fin", 'i', "File input", false, "out.pack");
	comm.add("list", '\0', "List files");
	comm.parse_check(argc, argv);
	comm.parse(argc, argv);
	string fin = comm.get<string>("fin");
	const char* fin_c = fin.c_str();
	maypack::Package pack(fin_c);
	vector<string> list = pack.getFileList();
	pack.close();
	if (list.size() == 0)
	{
		cerr << "\033[31mPackage file not exists...\033[0m" << endl;
		return 1;
	}
	cout << "totally " << list.size() << " files" << endl;
	for (size_t i = 0; i < list.size(); i++)
	{
		cout << list[i] << endl;
	}
	return 0;
}

int unpackall(int argc, char** argv)
{
	cmdline::parser comm;
	comm.set_program_name("maypack");
	comm.add<string>("fin", 'i', "File input", false, "out.pack");
	comm.add("unpackall", '\0', "Unpack all files");
	comm.parse_check(argc, argv);
	comm.parse(argc, argv);
	string fin = comm.get<string>("fin");
	const char* fin_c = fin.c_str();
	maypack::Package pack(fin_c);
	int rc = pack.unPackAll();
	pack.close();
	switch (rc)
	{
	case 1:
		cerr << "\033[31mUnpack fail...\033[0m" << endl;
		return 1;
		break;
	case 2:
		cerr << "\033[31mPackage file not exists...\033[0m" << endl;
		return 1;
		break;
	}

	return 0;
}

int main(int argc, char** argv)
{
	cmdline::parser comm;
	comm.set_program_name("maypack");
	comm.add<string>("fin", 'i', "File input", false, "out.pack");
	comm.add<string>("fout", 'o', "File output", false, "out");
	comm.add<string>("file", 'f', "Target file", false);
	comm.add("pack", '\0', "Packup Files");
	comm.add("list", '\0', "List files");
	comm.add("unpack", '\0', "Unpack exists file");
	comm.add("unpackall", '\0', "Unpack all files");
	comm.add("help", 'h', "Show this page");

	bool ok = comm.parse(argc, argv);

	if (!ok || argc == 1)
	{
		cerr << comm.usage();
		return 0;
	}

	if (comm.exist("help"))
	{
		cout << comm.usage();
		return 0;
	}

	vector<string> main_commands(4);
	main_commands[0] = "pack";
	main_commands[1] = "list";
	main_commands[2] = "unpack";
	main_commands[3] = "unpackall";

	int exists_count = 0;

	for (int i = 0; i < 4; i++)
	{
		if (comm.exist(main_commands[i]))
		{
			exists_count++;
		}
	}

	if (exists_count == 0)
	{
		cerr << "\033[33mYou should choice one running mode...\033[0m";
		cerr << comm.error() << endl;
		cerr << comm.usage();
		return 0;
	}

	if (exists_count > 1)
	{
		cerr << "\033[33mYou can only choice one running mode...\033[0m";
		cerr << comm.error() << endl;
		cerr << comm.usage();
		return 0;
	}

	int re = 0;
	if (comm.exist("pack"))
	{
		re = pack(argc, argv);
	}
	else if (comm.exist("unpack"))
	{
		re = unpack(argc, argv);
	}
	else if (comm.exist("list"))
	{
		re = list(argc, argv);
	}
	else if (comm.exist("unpackall"))
	{
		re = unpackall(argc, argv);
	}

	if (re != 0)
	{
		cerr << comm.usage();
	}

	return 0;
}
